package com.yycx.module.file.provider.oss.progress;

import com.yycx.module.file.provider.oss.listener.OnProgressListener;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 文件上传进度控制
 *
 * @author zyf
 */
public class ProgressInputStream extends FilterInputStream {
    private OnProgressListener onProgressListener;
    /**
     * 文件流对象
     */
    private InputStream inputStream;
    /**
     * 文件大小
     */
    private long fileSize;
    private long localSize;

    /**
     * 百分比
     */
    private long lastPercent;


    public ProgressInputStream(InputStream in, long fileSize, long localSize, OnProgressListener listener) {
        super(in);
        this.inputStream = in;
        this.fileSize = fileSize;
        this.localSize = localSize;
        this.lastPercent = (int) (this.localSize * 100 / this.fileSize);
        onProgressListener = listener;
    }


    public OnProgressListener getListener() {
        return onProgressListener;
    }


    /**
     * 读取后更新进度监视器
     */
    @Override
    public int read() {
        try {
            int readCount = inputStream.read();
            localSize += readCount;
            checkProgress();
            return readCount;
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
            return -1;
        }
    }


    /**
     * 读取后更新进度监视器
     */
    @Override
    public int read(byte[] b) throws IOException {
        try {
            int readCount = inputStream.read(b);
            localSize += readCount;
            checkProgress();
            return readCount;
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
            return -1;
        }
    }


    /**
     * 读取后更新进度监视器
     */
    @Override
    public int read(byte[] b, int offset, int length) throws IOException {
        try {
            int readCount = inputStream.read(b, offset, length);
            localSize += readCount;
            checkProgress();
            return readCount;
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
            return -1;
        }
    }


    /**
     * 跳过后更新进度监视器
     *
     * @param n
     * @return
     */
    @Override
    public long skip(long n) {
        try {
            return inputStream.skip(n);
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
            return -1;
        }
    }

    /**
     * 关闭进度监视器和流
     */
    @Override
    public void close() throws IOException {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
        }
    }

    @Override
    public void mark(int limit) {
        inputStream.mark(limit);
    }


    /**
     * 重置进度监视器和流
     */
    @Override
    public synchronized void reset() throws IOException {
        try {
            inputStream.reset();
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
        }

    }

    @Override
    public int available() {
        try {
            return inputStream.available();
        } catch (IOException e) {
            e.printStackTrace();
            onProgressListener.onError(e.getMessage());
            return -1;
        }
    }

    @Override
    public boolean markSupported() {
        return inputStream.markSupported();
    }

    private  void checkProgress() {
        int percent = (int) (localSize * 100 / fileSize);
        // 检查是否更新了进度
        if (percent - lastPercent >= 1) {
            lastPercent = percent;
            if (onProgressListener != null) {
                onProgressListener.onProgress(percent);
            }
        }
        // 检查是否完成
        if (percent == 100 && onProgressListener != null) {
            onProgressListener.onCompleted();
        }
    }
}